#include #include #include #include #include // Definiciones y variables del sensor DHT22 #define DHTPIN 4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); // Definiciones y variables del sensor de turbidez #define Turbidity_sensor A0 float Tension = 0.0; float NTU = 0.0; // Definiciones y variables del sensor de TDS #define TdsSensorPin A1 #define VREF 5.0 #define SCOUNT 30 int analogBuffer[SCOUNT]; int analogBufferTemp[SCOUNT]; int analogBufferIndex = 0, copyIndex = 0; float averageVoltage = 0, tdsValue = 0, waterTemperature = 25; // Definiciones y variables del sensor de nivel de agua y la electroválvula #define WaterLevelPin 5 #define ValvePin 10 bool isValveOpen = false; // Configuración de LCD LiquidCrystal_I2C lcd(0x27, 20, 4); // Dirección I2C, ancho y alto del LCD WiFiClient esp32Client; PubSubClient mqttClient(esp32Client); const char* ssid = "GALAXY12"; const char* password = "rgm12345"; const char* mqtt_server = "broker.emqx.io"; const int mqtt_port = 1883; const char* temperatura_topic = "SALIDA/01/temperatura"; const char* humedad_topic = "SALIDA/01/humedad"; const char* turbidez_topic = "SALIDA/01/turbidez"; const char* tds_topic = "SALIDA/01/tds"; const char* water_level_topic = "SALIDA/01/nivel_agua"; const char* valve_state_topic = "SALIDA/01/estado_valvula"; void wifiInit() { Serial.print("Conectándose a "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("Conectado a WiFi"); Serial.println("Dirección IP: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { // Tu función de callback } void reconnect() { while (!mqttClient.connected()) { Serial.print("Intentando conectarse MQTT..."); if (mqttClient.connect("ESP32Client")) { Serial.println("Conectado"); mqttClient.subscribe(temperatura_topic); mqttClient.subscribe(humedad_topic); mqttClient.subscribe(turbidez_topic); mqttClient.subscribe(tds_topic); mqttClient.subscribe(water_level_topic); mqttClient.subscribe(valve_state_topic); } else { Serial.print("Fallo, rc="); Serial.print(mqttClient.state()); Serial.println(" intentar de nuevo en 5 segundos"); delay(5000); } } } float square(float x) { return x * x; } float redondeo(float p_entera, int p_decimal) { float multiplicador = powf(10.0f, p_decimal); p_entera = roundf(p_entera * multiplicador) / multiplicador; return p_entera; } int getMedianNum(int bArray[], int iFilterLen) { int bTab[iFilterLen]; for (byte i = 0; i < iFilterLen; i++) bTab[i] = bArray[i]; int i, j, bTemp; for (j = 0; j < iFilterLen - 1; j++) { for (i = 0; i < iFilterLen - j - 1; i++) { if (bTab[i] > bTab[i + 1]) { bTemp = bTab[i]; bTab[i] = bTab[i + 1]; bTab[i + 1] = bTemp; } } } if ((iFilterLen & 1) > 0) bTemp = bTab[(iFilterLen - 1) / 2]; else bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2; return bTemp; } void clearLCDSection(int row, int col_start, int col_end) { lcd.setCursor(col_start, row); for (int i = col_start; i <= col_end; i++) { lcd.print(" "); } } void readAndPublishDHT() { float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); if (isnan(temperature) || isnan(humidity)) { Serial.println("Failed to read from DHT sensor!"); return; } char tempData[10]; char humData[10]; dtostrf(temperature, 4, 2, tempData); dtostrf(humidity, 4, 2, humData); mqttClient.publish(temperatura_topic, tempData); mqttClient.publish(humedad_topic, humData); Serial.print("Temperatura: "); Serial.print(temperature); Serial.println(" °C"); Serial.print("Humedad: "); Serial.print(humidity); Serial.println(" %"); clearLCDSection(0, 3, 7); // Limpia la sección donde se imprimen los valores de temperatura y humedad clearLCDSection(0, 11, 15); lcd.setCursor(0, 0); lcd.print("T: "); lcd.print(temperature); lcd.print("C H%: "); lcd.print(humidity); lcd.print("%"); } void readAndPublishTurbidity() { Tension = 0; for (int i = 0; i < 500; i++) { Tension += (((float)analogRead(Turbidity_sensor) / 1024) * 5) * 0.2544; } Tension = Tension / 500; Tension = redondeo(Tension, 1); if (Tension < 2.5) { NTU = 3000; } else { NTU = -1120.4 * square(Tension) + 5742.3 * Tension - 4352.9; } char turbidezData[10]; dtostrf(NTU, 4, 2, turbidezData); mqttClient.publish(turbidez_topic, turbidezData); Serial.print("Tensión: "); Serial.print(Tension); Serial.print(" V\t"); Serial.print("NTU: "); Serial.println(NTU); clearLCDSection(1, 6, 15); // Limpia la sección donde se imprime el valor de la turbidez lcd.setCursor(0, 1); lcd.print("Turb: "); lcd.print(NTU); lcd.print(" NTU"); } void readAndPublishTDS() { static unsigned long analogSampleTimepoint = millis(); if (millis() - analogSampleTimepoint > 40U) { analogSampleTimepoint = millis(); analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); analogBufferIndex++; if (analogBufferIndex == SCOUNT) { analogBufferIndex = 0; } } static unsigned long printTimepoint = millis(); if (millis() - printTimepoint > 800U) { printTimepoint = millis(); for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++) { analogBufferTemp[copyIndex] = analogBuffer[copyIndex]; } averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; float compensationCoefficient = 1.0 + 0.02 * (waterTemperature - 25.0); float compensationVoltage = averageVoltage / compensationCoefficient; tdsValue = (133.42 * compensationVoltage * compensationVoltage * compensationVoltage - 255.86 * compensationVoltage * compensationVoltage + 857.39 * compensationVoltage) * 0.5; char tdsData[10]; dtostrf(tdsValue, 4, 2, tdsData); mqttClient.publish(tds_topic, tdsData); Serial.print("TDS Value: "); Serial.print(tdsValue, 0); Serial.println(" ppm"); clearLCDSection(2, 5, 14); // Limpia la sección donde se imprime el valor de TDS lcd.setCursor(0, 2); lcd.print("TDS: "); lcd.print(tdsValue); lcd.print(" ppm"); } } void checkWaterLevel() { bool waterLevelHigh = digitalRead(WaterLevelPin) == LOW; // Suponiendo que LOW significa que el tanque está lleno char waterLevelData[10]; dtostrf(waterLevelHigh, 1, 0, waterLevelData); mqttClient.publish(water_level_topic, waterLevelData); Serial.print("Nivel de agua: "); Serial.println(waterLevelHigh ? "ALTO (tanque lleno)" : "BAJO (tanque no lleno)"); if (waterLevelHigh) { if (isValveOpen) { digitalWrite(ValvePin, LOW); // Cierra la electroválvula isValveOpen = false; mqttClient.publish(valve_state_topic, "CERRADA"); Serial.println("Electroválvula CERRADA"); } } else { if (!isValveOpen) { digitalWrite(ValvePin, HIGH); // Abre la electroválvula isValveOpen = true; mqttClient.publish(valve_state_topic, "ABIERTA"); Serial.println("Electroválvula ABIERTA"); } } clearLCDSection(3, 7, 14); // Limpia la sección donde se imprime el nivel de agua lcd.setCursor(0, 3); lcd.print("LEVEL: "); lcd.print(waterLevelHigh ? "Full " : "not full "); //lcd.print("Valvula: "); //lcd.print(isValveOpen ? "Abierta" : "Cerrada"); } void setup() { Serial.begin(115200); wifiInit(); mqttClient.setServer(mqtt_server, mqtt_port); mqttClient.setCallback(callback); dht.begin(); // Inicializar el sensor DHT22 pinMode(TdsSensorPin, INPUT); pinMode(WaterLevelPin, INPUT); pinMode(ValvePin, OUTPUT); digitalWrite(ValvePin, LOW); // Asegura que la electroválvula esté cerrada al inicio lcd.init(); lcd.backlight(); Serial.println("Lectura de sensores y envío de datos a MQTT"); } void loop() { if (!mqttClient.connected()) { reconnect(); } mqttClient.loop(); readAndPublishDHT(); readAndPublishTurbidity(); readAndPublishTDS(); checkWaterLevel(); delay(5000); // Ajusta el delay si es necesario para tus requerimientos }